using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using WorkLogSystem.Common;
using WorkLogSystem.Entity;
using WorkLogSystem.Service;

namespace WebApiDemo.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IMemoryCache _cache;
        private readonly ILogger<AuthController> _logger;
        private readonly UserService _userService;

        public AuthController(IMemoryCache cache, ILogger<AuthController> logger,UserService userService)
        {
            _cache = cache;
            _logger = logger;
            _userService = userService;
        }

        [HttpPost]
        public ResultModel Login(object sender)
        {
            ResultModel res = new ResultModel();
            Dictionary<string, string> userDic = JsonConvert.DeserializeObject<Dictionary<string, string>>(sender.ToString());
            User user = _userService.GetUserByName(userDic["cUserName"]);
            if (user != null && user.cPassword == StringSecurity.MD5Encrypt(userDic["cPassword"]))
            {
                var userTokenKey = $"user_token_{userDic["cUserName"]}";
                if (_cache.TryGetValue(userTokenKey, out string existingToken))
                {
                    _cache.Remove($"auth_token_{existingToken}");
                }
                string token = "Simple_" + Guid.NewGuid().ToString();
                UserInfo userInfo = new UserInfo();
                userInfo.ID = user.ID;
                userInfo.cUserName = user.cUserName;
                userInfo.cPhone = user.cPhone;
                userInfo.cGender= user.cGender;
                var options = new MemoryCacheEntryOptions()
                    .SetAbsoluteExpiration(DateTimeOffset.Now.AddHours(24))// 最长2小时
                    .SetSlidingExpiration(TimeSpan.FromHours(1));      // 10分钟不访问则过期
                _cache.Set("auth_token_" + token, userInfo, options);

                var options2 = new MemoryCacheEntryOptions()
                    .SetAbsoluteExpiration(DateTimeOffset.Now.AddHours(24));
                _cache.Set(userTokenKey, token, options2);
                res.Code = ResultCode.Success;
                res.Message = "登录成功";
                res.Result = new { token, userInfo };
            }
            else
            {
                res.Code = ResultCode.Fail;
                res.Message = "用户名或密码错误";
            }
            return res;

        }

        [HttpPost]
        [Authorize]
        public ResultModel Logout()
        {
            ResultModel res = new ResultModel();
            _cache.Remove("auth_token_" + User.FindFirst("Token")?.Value);
            _cache.Remove("user_token_" + User.FindFirst("UserId")?.Value);
            res.Code = ResultCode.Success;
            res.Message = "退出成功";
            return res;
        }

        [HttpPost]
        [Authorize]
        public ResultModel UpdatePassword(object sender)
        {
            ResultModel res = new ResultModel();
            Dictionary<string, string> userDic = JsonConvert.DeserializeObject<Dictionary<string, string>>(sender.ToString());
            if (string.IsNullOrWhiteSpace(userDic["cNewPassword"]))
            {
                res.Code = ResultCode.Fail;
                res.Message = "新密码不能为空";
            }
            User u = new User();
            u.ID = User.FindFirst("ID").Value;
            User user = _userService.GetItem(u);

            if (user.cPassword == StringSecurity.MD5Encrypt(userDic["cOldPassword"]))
            {
                Dictionary<string, object> dic = new Dictionary<string, object>();
                dic["ID"] = User.FindFirst("ID").Value;
                dic["cPassword"] = StringSecurity.MD5Encrypt(userDic["cNewPassword"]);
                _userService.UpdateItem(dic);
                res.Code = ResultCode.Success;
                res.Message = "修改成功";
            }
            else
            {
                res.Code = ResultCode.Fail;
                res.Message = "旧密码错误";
            }
            return res;
        }
    }
}
